{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Changelog\n",
    "#### 1. 使用原始数据，未做normalize，使用2层same padding(k_size=3,padding=1)卷积，步长为2的池化，两个全连接层，88.7%的准确率(Linux platform)\n",
    "#### 2. 和1中的所有操作相同的，但是做了normalize，准确率88.84%(linux platform)\n",
    "#### 3. 利用2中的regularization，将卷积核的大小改为5，padding为2，准确率为89.15%(windows platform)\n",
    "#### 4. 在3的基础上，更换optimizer算法由SGD变为Adam，准确率为89.59%(Linux platform)\n",
    "#### 5. 在2的基础上，更换optimizer算法由SGD变为Adam，准确率为89.9%(Linux platform)\n",
    "#### 6. 加入net.eval(),准确率上升到90.94%(Linux platform)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "import torch.nn.functional as F\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "label_to_description = {0: 'T-shirt/top', 1: 'Trouser', 2: 'Pullover', 3: 'Dress',\n",
    "                        4: 'Coat', 5: 'Sandal', 6: 'Shirt',\n",
    "                       7: 'Sneaker', 8: 'Bag', 9: 'Ankle boot',\n",
    "                        }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([60000, 28, 28]) torch.Size([60000])\n",
      "tensor(9)\n",
      "tensor(0)\n"
     ]
    }
   ],
   "source": [
    "path_to_datasets = '/home/lor/Datasets/FashionMNIST/FashionMNIST/processed/training.pt'\n",
    "# path_to_datasets = 'E:/data/FashionMNIST/FashionMNIST/processed/training.pt'\n",
    "samples = torch.load(path_to_datasets)\n",
    "features = samples[0]\n",
    "targets = samples[1]\n",
    "print(features.shape, targets.shape)\n",
    "print(targets.max())\n",
    "print(targets.min())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = plt.subplot(2, 2, 1)\n",
    "plt.imshow(np.array(features[3]), cmap='gray')\n",
    "ax.set_title(label_to_description[targets.storage()[3]])\n",
    "ax = plt.subplot(2, 2, 2)\n",
    "plt.imshow(np.array(features[4]), cmap='gray')\n",
    "ax.set_title(label_to_description[targets.storage()[4]])\n",
    "plt.show()\n",
    "# plt.title(label_to_description[targets.storage()[3]])\n",
    "# label_to_description[targets.storage()[3]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "from torch.utils.data import Dataset, DataLoader"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "class UserDataset(Dataset):\n",
    "    def __init__(self, features, targets):\n",
    "        self.features = features\n",
    "        self.targets = targets\n",
    "        \n",
    "    def __len__(self):\n",
    "        return len(self.targets)\n",
    "    \n",
    "    def __getitem__(self, idx):\n",
    "        target = self.targets[idx]\n",
    "        feature = self.features[idx].unsqueeze(0).float()\n",
    "        feature = (feature - torch.min(feature)) / (torch.max(feature) - torch.min(feature))\n",
    "        return (target, feature)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_dataset = UserDataset(features, targets)\n",
    "train_dataloader = DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([0, 8, 2, 0, 1, 8, 8, 1, 9, 2, 1, 2, 5, 3, 7, 7, 8, 8, 2, 5, 4, 0, 7, 7,\n",
       "        9, 4, 9, 6, 6, 3, 1, 9])"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "one_iter = next(iter(train_dataloader))\n",
    "one_iter[0].reshape(-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "collapsed": true,
    "jupyter": {
     "outputs_hidden": true
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 10 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "for i in range(10):\n",
    "    ax = plt.subplot(2, 5, i + 1)\n",
    "    plt.imshow(one_iter[1][i][0], cmap='gray')\n",
    "    plt.axis('off')\n",
    "    ax.set_title(label_to_description[one_iter[0].storage()[i]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Network(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(Network, self).__init__()\n",
    "        \n",
    "        self.conv1 = nn.Sequential(\n",
    "                        nn.Conv2d(1, 16, kernel_size=(3, 3), stride=1, padding=1),\n",
    "                        nn.BatchNorm2d(16),\n",
    "                        nn.ReLU(),\n",
    "                        nn.MaxPool2d(kernel_size=(2, 2), stride=2)\n",
    "        )\n",
    "        \n",
    "        self.conv2 = nn.Sequential(\n",
    "                        nn.Conv2d(16, 24, kernel_size=(3, 3), stride=1, padding=1),\n",
    "                        nn.BatchNorm2d(24),\n",
    "                        nn.ReLU(),\n",
    "                        nn.MaxPool2d(kernel_size=(2, 2), stride=2)\n",
    "        )\n",
    "        \n",
    "        self.fc1 = nn.Linear(7 * 7 * 24, 120)\n",
    "        self.fc2 = nn.Linear(120, 10)\n",
    "    \n",
    "    def forward(self, x):\n",
    "        out = self.conv1(x)\n",
    "        out = self.conv2(out)\n",
    "        out = out.reshape(out.shape[0], -1)\n",
    "        out = self.fc1(out)\n",
    "        res = self.fc2(F.relu(out))\n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [],
   "source": [
    "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
    "net = Network()\n",
    "net.to(device)\n",
    "loss = nn.CrossEntropyLoss()\n",
    "# optimizer = optim.SGD(net.parameters(), lr=1e-3)\n",
    "optimizer = optim.Adam(net.parameters(), lr=1e-3)\n",
    "\n",
    "total_step = len(train_dataloader)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "num_epochs = 10\n",
    "net.train()\n",
    "for epoch in range(num_epochs):\n",
    "    for i, (target, feature) in enumerate(train_dataloader):\n",
    "        target, feature = target.to(device), feature.to(device)\n",
    "        out = net(feature)\n",
    "#         out = out.reshape(-1)\n",
    "        target = target.reshape(-1)\n",
    "        criterion = loss(out, target)\n",
    "        \n",
    "        optimizer.zero_grad()\n",
    "        criterion.backward()\n",
    "        optimizer.step()\n",
    "        \n",
    "        if (i + 1) % 100 == 0:\n",
    "            print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}' \n",
    "                   .format(epoch+1, num_epochs, i+1, total_step, criterion.item()))\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([10000, 28, 28])\n",
      "torch.Size([10000])\n"
     ]
    }
   ],
   "source": [
    "### 验证\n",
    "# test_path = 'E:/data/FashionMNIST/FashionMNIST/processed/test.pt'\n",
    "test_path = '/home/lor/Datasets/FashionMNIST/FashionMNIST/processed/test.pt'\n",
    "test_dataset = torch.load(test_path)\n",
    "print(test_dataset[0].shape)\n",
    "print(test_dataset[1].shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_dataset = UserDataset(test_dataset[0], test_dataset[1])\n",
    "test_dataloader = DataLoader(test_dataset, batch_size=1, shuffle=True, num_workers=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 91.07%\n"
     ]
    }
   ],
   "source": [
    "total = 10000\n",
    "pred_count = 0\n",
    "net.eval()\n",
    "for (target, feature) in test_dataloader:\n",
    "#     print(target.shape)\n",
    "#     print(feature.shape)\n",
    "    target = target.to(device)\n",
    "    feature = feature.to(device)\n",
    "    out = net(feature)\n",
    "#     print(torch.argmax(out, 1))\n",
    "#     print(target)\n",
    "#     print(torch.argmax(out, 1) == target)\n",
    "#     print((torch.argmax(out, 1) == target).sum().item())\n",
    "    pred_count = pred_count + (torch.argmax(out, 1) == target).sum().item()\n",
    "#     break\n",
    "print(\"Accuracy: {0}%\".format(100 * pred_count / total))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Save the model\n",
    "torch.save(net.state_dict(), './net.pt')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<All keys matched successfully>"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Load the model\n",
    "oth_net = Network()\n",
    "oth_net.load_state_dict(torch.load('./net.pt'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Network(\n",
       "  (conv1): Sequential(\n",
       "    (0): Conv2d(1, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "    (2): ReLU()\n",
       "    (3): MaxPool2d(kernel_size=(2, 2), stride=2, padding=0, dilation=1, ceil_mode=False)\n",
       "  )\n",
       "  (conv2): Sequential(\n",
       "    (0): Conv2d(16, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (1): BatchNorm2d(24, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "    (2): ReLU()\n",
       "    (3): MaxPool2d(kernel_size=(2, 2), stride=2, padding=0, dilation=1, ceil_mode=False)\n",
       "  )\n",
       "  (fc1): Linear(in_features=1176, out_features=32, bias=True)\n",
       "  (fc2): Linear(in_features=32, out_features=10, bias=True)\n",
       ")"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "oth_net.eval()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
